package com.sino.operation.service.business;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.sino.operation.commons.commonEnum.ChargeInfoEnum;
import com.sino.operation.commons.commonEnum.TaskStateEnum;
import com.sino.operation.entity.BizAccountmanageInfo;
import com.sino.operation.entity.BizChargeMethods;
import com.sino.operation.entity.BizTranslist;
import com.sino.operation.entity.SysAbMessage;
import com.sino.operation.mapper.BizAccountmanageInfoMapper;
import com.sino.operation.mapper.BizChargeMethodsMapper;
import com.sino.operation.mapper.BizTranslistMapper;
import com.sino.operation.mapper.SysAbMessageMapper;
import com.sino.operation.param.ChargeSubTradeParam;
import com.sino.operation.param.out.CenterDataAccount;
import com.sino.operation.param.out.EscBodyByAccount;
import com.sino.operation.param.out.EscReceiveByCounterToAccount;
import com.sino.operation.peripheral.esc.request.CoreHead;
import com.sino.operation.peripheral.esc.request.core.EscCore2110Param;
import com.sino.operation.peripheral.esc.request.core.EscCore4010Param;
import com.sino.operation.peripheral.esc.request.core.body.EscBodyCore2110;
import com.sino.operation.peripheral.esc.request.core.body.EscBodyCore4010;
import com.sino.operation.peripheral.esc.response.EscRet;
import com.sino.operation.peripheral.esc.response.core.EscCore2110Dto;
import com.sino.operation.peripheral.esc.response.core.EscCore4010Dto;
import com.sino.operation.peripheral.esc.response.core.body.EscResBody4010;
import com.sino.operation.service.business.inter.AccountChargeService;
import com.sino.operation.util.*;
import com.sino.operation.vo.PublicInfo;
import com.sino.operation.vo.current.CurrentStartMarkParam;
import com.sino.operation.vo.current.FieldInformation;
import com.sino.operation.vo.current.InfoInput;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName AccountChargeServiceImpl
 * @Description TOD
 * @Author 北陈
 * @Date 2021/11/1 14:22
 * @Version 1.0
 */
@Service
public class AccountChargeServiceImpl implements AccountChargeService {

    @Autowired
    private UrlUtil urlUtil;

    @Autowired
    private RestTemplateUtils restTemplateUtils;

    @Autowired
    private StringRedisTemplate redis;

    @Autowired(required = false)
    private SysAbMessageMapper sysAbMessageMapper;

    @Autowired(required = false)
    private BizTranslistMapper bizTranslistMapper;

    @Autowired(required = false)
    private BizChargeMethodsMapper bizChargeMethodsMapper;

    @Autowired(required = false)
    private BizAccountmanageInfoMapper bizAccountmanageInfoMapper;
    /**
     *
     * @description {对公活期/财政性活期新建客户信息}
     * @param bizTranslist
     * @param bizAccountmanageInfo
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:08
     **/
    @Override
    public void AccountNewCurrent(BizTranslist bizTranslist, BizAccountmanageInfo bizAccountmanageInfo) {
        EscReceiveByCounterToAccount toAccount = this.getMessage(bizTranslist.getJournalNo(), EscReceiveByCounterToAccount.class);
        EscBodyByAccount escBodyByAccount = toAccount.getEscBodyByAccount();
        CenterDataAccount centerDataAccount = escBodyByAccount.getCenterDataAccount();
        CurrentStartMarkParam currentStartMarkParam = centerDataAccount.getCurrentStartMarkParam();
        String startMark = currentStartMarkParam.getStartMark();
        if (ChargeInfoEnum.CURRENT_NEW_OPEN.getCode().equals(startMark)){
            //对公活期新建客户并开户
            //1、先新建客户信息,调用4010接口
            //客户中文名
            String clientCn="";
            //法人名称
            String frmc="";
            //法人证件类型
            String frzjlx="";
            //法人证件号码
            String frzjhm="";
            //法人证件有效期
            String frzjyxq="";
            //法人证件签发日期
            String frzjqf="";
            //账户分类
            String zhfl="";
            //账户属性
            String zhsx="";
            //通兑范围
            String tdfw="";
            //支付条件
            String zftj="";
            //产品类型
            String cplx="";
            //币种
            String currency="";
            List<InfoInput> infoInputs = centerDataAccount.getInfoInputs();
            for (InfoInput infoInput:infoInputs){
                if ("KH_BASE_INFO".equals(infoInput.getInfoEnglishName())){
                    List<FieldInformation> listFieldInformation = infoInput.getListFieldInformation();
                    for (FieldInformation fieldInformation:listFieldInformation){
                        if ("CUST_CHINS_NM".equals(fieldInformation.getEnglishName())){
                            clientCn=(String)fieldInformation.getFieldValue();
                        }
                    }

                }
                if ("BASE_INFO".equals(infoInput.getInfoEnglishName())){
                    List<FieldInformation> listFieldInformation = infoInput.getListFieldInformation();
                    for (FieldInformation fieldInformation:listFieldInformation){
                        if ("ACCT_CLASF".equals(fieldInformation.getEnglishName())){
                            zhfl=(String)fieldInformation.getFieldValue();
                        }
                        if ("PROD_CODE".equals(fieldInformation.getEnglishName())){
                            cplx=(String)fieldInformation.getFieldValue();
                        }
                        if ("CCY_CODE_NUM".equals(fieldInformation.getEnglishName())){
                            currency=(String) fieldInformation.getFieldValue();
                            break;
                        }
                    }
                }

                if ("ACCONUT_INFO".equals(infoInput.getInfoEnglishName())){
                    List<FieldInformation> listFieldInformation = infoInput.getListFieldInformation();
                    for (FieldInformation fieldInformation:listFieldInformation){
                        if ("ACCT_ATTR".equals(fieldInformation.getEnglishName())){
                            zhsx=(String)fieldInformation.getFieldValue();
                        }
                        if ("UNVSL_WTHDG_SCOPE".equals(fieldInformation.getEnglishName())){
                            tdfw=(String)fieldInformation.getFieldValue();
                        }
                        if ("PYMT_COND".equals(fieldInformation.getEnglishName())){
                            zftj=(String)fieldInformation.getFieldValue();
                        }
                    }
                }

                if ("KH_FR_INFO".equals(infoInput.getInfoEnglishName())){
                    List<FieldInformation> listFieldInformation = infoInput.getListFieldInformation();
                    for (FieldInformation fieldInformation:listFieldInformation){
                        if ("CORPT_RPRTV_NM".equals(fieldInformation.getEnglishName())){
                            frmc=(String)fieldInformation.getFieldValue();
                        }
                        if ("CORPT_RPRTV_DOCS_CATG".equals(fieldInformation.getEnglishName())){
                            frzjlx=(String)fieldInformation.getFieldValue();
                        }
                        if ("CORPT_RPRTV_DOCS_NUM".equals(fieldInformation.getEnglishName())){
                            frzjhm=(String)fieldInformation.getFieldValue();
                        }
                        if ("LGL_PERN_DOCS_VLD_DT".equals(fieldInformation.getEnglishName())){
                            frzjyxq=(String)fieldInformation.getFieldValue();
                        }
                        if ("CORPT_RPRTV_DOCS_ISSUE_DT".equals(fieldInformation.getEnglishName())){
                            frzjqf=(String)fieldInformation.getFieldValue();
                        }
                    }
                }
            }
            CoreHead coreHead = new CoreHead();
            coreHead.setReqResFlg("req");
            String journalNo = bizTranslist.getJournalNo();
            String core4010Url = urlUtil.getCoreUrl("4010");
            String escToken = this.redis.opsForValue().get("escToken");
            EscCore4010Param escCore4010Param = EscRequestTestUtil.getEscCore4010Param(journalNo,"4010",escToken);
            EscBodyCore4010 escBodyCore4010=EscBodyCore4010.builder().coreHead(coreHead).custChinsNm(clientCn)
                    .corptRprtvDocsCatg(frzjlx).corptRprtvNm(frmc).corptRprtvDocsNum(frzjhm)
                    .lglPernDocsVldDt(frzjyxq).corptRprtvDocsIssueDt(frzjqf).build();
            escCore4010Param.setEscBodyCore4010(escBodyCore4010);
            ResponseEntity<EscCore4010Dto> post = restTemplateUtils.post(core4010Url, escCore4010Param, EscCore4010Dto.class);
            EscCore4010Dto escCore4010Dto = post.getBody();
            String retStatus = escCore4010Dto.getEscResSysHead().getRetStatus();
            List<EscRet> rets = escCore4010Dto.getEscResSysHead().getRets();
            String retCode = rets.get(0).getRetCode();
            String retMsg = rets.get(0).getRetMsg();
            if ("F".equals(retStatus)) {
                //建立客户信息失败
                bizTranslist.setTransState(TaskStateEnum.TRANS_ERROR.getCode());
                bizTranslist.setHxResponseCode(retCode);
                bizTranslist.setHxResponseDesc(retMsg);
                //发送到柜面
            }else {
                EscResBody4010 escResBody4010 = escCore4010Dto.getEscResBody4010();
                //客户号
                String custNum = escBodyCore4010.getCustNum();
                //客户中文名
                String custChinsNm = escBodyCore4010.getCustChinsNm();

                bizTranslist.setClientNo(custNum);
                //bizAccountmanageInfo.setCunm(custChinsNm);



                HashMap<String, String> map = new HashMap<>(16);
                map.put("quickFlg","1");
                map.put("apvlFilgFlg","1");
                map.put("ccyCodeNum",currency);
                map.put("prodCode",cplx);
                map.put("acctClasf",zhfl);
                map.put("acctAttr",zhsx);
                map.put("unvslWthdqScope",tdfw);
                map.put("pymtCond",zftj);
                this.clientOpenNewByAccount(escCore4010Dto,map,bizTranslist,bizAccountmanageInfo);

            }

        }
        //endregion
        //region 判断该交易记账有没自助回单、短信通等子交易
        HashOperations<String, Object, Object> opsForHash = redis.opsForHash();
        List<BizChargeMethods> bizChargeMethods=null;
        bizChargeMethods = (List<BizChargeMethods>)opsForHash.get("tran_code:" + bizTranslist.getTransCode(), "execute_mark:1");
        if (CollectionUtils.isEmpty(bizChargeMethods)){
            QueryWrapper<BizChargeMethods> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("tran_code",bizTranslist.getTransCode());
            queryWrapper.eq("execute_mark","1");
            bizChargeMethods = bizChargeMethodsMapper.selectList(queryWrapper);
            opsForHash.put("tran_code:"+bizTranslist.getTransCode(), "execute_mark:1",bizChargeMethods);
        }
        if (bizChargeMethods.size()>0){
            ChargeSubTradeParam chargeSubTradeParam = new ChargeSubTradeParam();
            //从日志表中查询这一笔交易号传过来的报文
            chargeSubTradeParam.setSmsMark(currentStartMarkParam.getSmsMark());
            chargeSubTradeParam.setSelfList(currentStartMarkParam.getSelfList());
            chargeSubTradeParam.setPreSample(currentStartMarkParam.getPreSample());
            bizChargeMethods.forEach(bizChargeMethod->{
                ReflectExecuteUtil.executeCharge(bizChargeMethod.getClassName(),bizChargeMethod.getServiceName(),chargeSubTradeParam);
            });
        }
    }

    /**
     *
     * @description {对公活期/财政性活期开户}
     * @param escCore4010Dto
     * @param map
     * @param bizTranslist
     * @param bizAccountmanageInfo
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:09
     **/
    @Override
    public void clientOpenNewByAccount(EscCore4010Dto escCore4010Dto,Map<String,String> map,BizTranslist bizTranslist,BizAccountmanageInfo bizAccountmanageInfo) {
        String journalNo = bizTranslist.getJournalNo();
        EscResBody4010 escResBody4010 = escCore4010Dto.getEscResBody4010();
        //客户号
        String custNum = escResBody4010.getCustNum();
        //客户中文名
        String custChinsNm = escResBody4010.getCustChinsNm();
        String quickFlg = map.get("quickFlg");
        String apvlFilgFlg = map.get("apvlFilgFlg");
        String ccyCodeNum = map.get("ccyCodeNum");
        String prodCode = map.get("prodCode");
        String acctClasf = map.get("acctClasf");
        String acctAttr = map.get("acctAttr");
        String unvslWthdqScope = map.get("unvslWthdqScope");
        String pymtCond = map.get("pymtCond");
        bizTranslist.setClientNo(custNum);
        //bizAccountmanageInfo.setCunm(custChinsNm);
        //调用2110接口去完成开户
        CoreHead coreHead = new CoreHead();
        coreHead.setReqResFlg("req");
        EscBodyCore2110 escBodyCore2110=EscBodyCore2110.builder().coreHead(coreHead).custTp("2").custNum(custNum)
                .openAcctQuickFlg(quickFlg).apvlFilgFlg(apvlFilgFlg).ccyCodeNum(ccyCodeNum)
                .prodCode(prodCode).acctClasf(acctClasf).acctAttr(acctAttr)
                .unvslWthdqScope(unvslWthdqScope).pymtCond(pymtCond).build();
        EscCore2110Param escCore2110Param = EscRequestTestUtil.getEscCore2110Param(journalNo);
        escCore2110Param.setEscBodyCore2110(escBodyCore2110);
        String core2110Url = this.urlUtil.getCoreUrl("2110");
        ResponseEntity<EscCore2110Dto> post1 = this.restTemplateUtils.post(core2110Url, escCore2110Param, EscCore2110Dto.class);
        EscCore2110Dto core2110Dto = post1.getBody();
        String status = core2110Dto.getEscResSysHead().getRetStatus();
        if ("F".equals(status)){
            bizTranslist.setTransState(TaskStateEnum.NEW_CLIENT_OPEN_ERROR.getCode());
        }else {
            //开户账号
            String custAcctNum = core2110Dto.getEscResBody2110().getCustAcctNum();
            bizTranslist.setClientAcctNo(custAcctNum);
            bizTranslist.setTransState(TaskStateEnum.TRANS_SUCCESS.getCode());
        }
    }

    /**
     *
     * @description {同业活期新建客户信息}
     * @param bizTranslist
     * @param bizAccountmanageInfo
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:10
     **/
    @Override
    public void AccountNewIndustry(BizTranslist bizTranslist, BizAccountmanageInfo bizAccountmanageInfo) {

    }

    /**
     *
     * @description {同业活期开户}
     * @param persistenceUtil
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:10
     **/
    @Override
    public void clientOpenNewByIndustry(PersistenceUtil persistenceUtil) {

    }

    /**
     *
     * @description {变更开户的对公活期/财政性活期变更}
     * @param bizTranslist
    * @param bizAccountmanageInfo
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:11
     **/
    @Override
    public void changeNewByCurrent(BizTranslist bizTranslist, BizAccountmanageInfo bizAccountmanageInfo) {

    }

    /**
     *
     * @description {变更客户开户的同业活期变更}
     * @param bizTranslist
     * @param bizAccountmanageInfo
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:12
     **/
    @Override
    public void changeNewByByIndustry(BizTranslist bizTranslist, BizAccountmanageInfo bizAccountmanageInfo) {

    }

    /**
     *
     * @description {活期变更}
     * @param journalNo
     * @param persistenceUtil
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:15
     **/
    @Override
    public void currentChange(String journalNo, PersistenceUtil persistenceUtil) {

    }

    /**
     *
     * @description {定期变更}
     * @param journalNo
     * @param persistenceUtil
     * @return void
     * @author 北陈
     * @date 2021/11/3 0003 23:15
     **/
    @Override
    public void regularChange(String journalNo, PersistenceUtil persistenceUtil) {

    }

    @Override
    public void closeClient(String journalNo, PersistenceUtil persistenceUtil) {

    }

    /**
     *
     * @description {根据流水表获取并转换为相应的对象}
     * @param journalNo
     * @return T
     * @author 北陈
     * @date 2021/11/3 0003 22:49
     **/
    @Override
    public <T> T getMessage(String journalNo,Class<T> clzz) {
        SysAbMessage sysAbMessage=this.sysAbMessageMapper.selectById(journalNo);
        String messageAccept = sysAbMessage.getMessageAccept();
        T t = JSONUtil.toBean(JSONUtil.parseObj(messageAccept), clzz);
        return t;
    }


}
